---
title: Angle Slider
description: Using the angle slider machine in your project.
package: "@zag-js/angle-slider"
---

An angle slider is a circular dial that allows users to select an angle,
typically in degrees, within a 360° range. It provides an intuitive way to
control rotations or orientations, offering accessibility features.

<Resources pkg="@zag-js/angle-slider" />

<Showcase id="AngleSlider" />

**Features**

- Fully managed keyboard navigation
- Supports touch or click on track to update value
- Supports Right-to-Left directionality

## Installation

To use the angle slider machine in your project, run the following command in
your command line:

<CodeSnippet id="angle-slider/installation.mdx" />

## Anatomy

To set up the angle slider correctly, you'll need to understand its anatomy and
how we name its parts.

> Each part includes a `data-part` attribute to help identify them in the DOM.

<Anatomy id="angle-slider" />

## Usage

First, import the angle-slider package into your project

```jsx
import * as angleSlider from "@zag-js/angle-slider"
```

The angle slider package exports two key functions:

- `machine` — The state machine logic for the angle slider widget as described
  in the WAI-ARIA spec.
- `connect` — The function that translates the machine's state to JSX attributes
  and event handlers.

> You'll need to provide a unique `id` to the `useMachine` hook. This is used to
> ensure that every part has a unique identifier.

Next, import the required hooks and functions for your framework and use the
angle slider machine in your project 🔥

<CodeSnippet id="angle-slider/usage.mdx" />

### Setting the initial value

Use the `defaultValue` property to set the initial value of the angle slider.

```jsx {2}
const service = useMachine(angleSlider.machine, {
  defaultValue: 45,
})
```

### Controlled angle slider

To control the angle slider's value, pass the `value` and `onValueChange`
properties to the machine function.

<CodeSnippet id="angle-slider/controlled.mdx" />

### Setting the value's granularity

By default, the granularity, is `1`, meaning that the value is always an
integer. You can change the step attribute to control the granularity.

For example, If you need a value between `5` and `10`, accurate to two decimal
places, you should set the value of step to `0.01`:

```jsx {2}
const service = useMachine(angleSlider.machine, {
  step: 0.01,
})
```

### Listening for changes

When the angle slider value changes, the `onValueChange` and `onValueChangeEnd`
callbacks are invoked. You can use this to setup custom behaviors in your app.

```jsx {2-7}
const service = useMachine(angleSlider.machine, {
  onValueChange(details) {
    console.log("value is changing to:", details)
  },
  onValueChangeEnd(details) {
    console.log("value has changed to:", details)
  },
})
```

### Usage within forms

To use angle slider within forms, use the exposed `hiddenInputProps` from the
`connect` function and ensure you pass `name` value to the machine's context. It
will render a hidden input and ensure the value changes get propagated to the
form correctly.

```jsx {2}
const service = useMachine(angleSlider.machine, {
  name: "wind-direction",
})
```

### Using angle slider marks

To show marks or ticks along the angle slider track, use the exposed
`api.getMarkerProps()` method to position the angle slider marks at desired
angles.

<CodeSnippet id="angle-slider/tick-marks.mdx" />

## Styling guide

Earlier, we mentioned that each angle slider part has a `data-part` attribute
added to them to select and style them in the DOM.

### Disabled State

When the angle slider is disabled, the `data-disabled` attribute is added to the
root, label, control, thumb and marker.

```css
[data-part="root"][data-disabled] {
  /* styles for root disabled state */
}

[data-part="label"][data-disabled] {
  /* styles for label disabled state */
}

[data-part="control"][data-disabled] {
  /* styles for control disabled state */
}

[data-part="thumb"][data-disabled] {
  /* styles for thumb disabled state */
}

[data-part="range"][data-disabled] {
  /* styles for thumb disabled state */
}
```

### Invalid State

When the slider is invalid, the `data-invalid` attribute is added to the root,
track, range, label, and thumb parts.

```css
[data-part="root"][data-invalid] {
  /* styles for root invalid state */
}

[data-part="label"][data-invalid] {
  /* styles for label invalid state */
}

[data-part="control"][data-invalid] {
  /* styles for control invalid state */
}

[data-part="valueText"][data-invalid] {
  /* styles for output invalid state */
}

[data-part="thumb"][data-invalid] {
  /* styles for thumb invalid state */
}

[data-part="marker"][data-invalid] {
  /* styles for marker invalid state */
}
```

### Styling the markers

```css
[data-part="marker"][data-state="(at|under|over)-value"] {
  /* styles for when the value exceeds the marker's value */
}
```

## Methods and Properties

### Machine Context

The slider machine exposes the following context properties:

<ContextTable name="angle-slider" />

### Machine API

The slider `api` exposes the following methods:

<ApiTable name="angle-slider" />

### Data Attributes

<DataAttrTable name="angle-slider" />

### CSS Variables

<CssVarTable name="angle-slider" />

### Keyboard Interactions

<KeyboardTable name="angle-slider" />
